package cn.edu.swu.miniwebsvr.core;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;


public class HttpParser {
    public static Parameter parse(InputStream inputStream) throws IOException {
        Parameter parameter = new Parameter();
        // 使用缓冲字符流读取，便于按行处理文本协议
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(inputStream, StandardCharsets.UTF_8)
        );
        // TODO: [222024321072055/苏雨征]
        // 1. 读取并解析 HTTP 请求行 (e.g., GET /path?param=value HTTP/1.1)
        String requestLine = reader.readLine();
        if (requestLine == null || requestLine.isEmpty()) {
            throw new IOException("无效的请求行");
        }
        parseRequestLine(requestLine, parameter);
        // 2. 循环读取并解析所有 HTTP 请求头 (e.g., Host: localhost:8080)
        String headerLine;
        while ((headerLine = reader.readLine()) != null && !headerLine.isEmpty()) {
            parseHeaderLine(headerLine, parameter);
        }
        // 3. 根据请求方法 (Method) 和请求头 (Content-Length, Content-Type) 判断并读取请求体
        if ("POST".equalsIgnoreCase(parameter.getMethod())) {
            parseRequestBody(reader, parameter);
        }
        return parameter;
    }

    // TODO: [222024321072055/苏雨征] 可以添加辅助方法来简化字符串解析和 URL 解码
    private static void parseRequestLine(String requestLine, Parameter parameter) throws IOException {
        String[] parts = requestLine.split("\\s+"); // 按空格分割（支持多个空格）
        if (parts.length < 3) {
            throw new IOException("请求行格式错误: " + requestLine);
        }

        // 提取请求方法（GET/POST）
        String method = parts[0];
        parameter.setMethod(method);

        // 提取 URL 并解析 URL 参数（如 /path?a=1&b=2）
        String url = parts[1];
        int queryIndex = url.indexOf('?');
        if (queryIndex != -1) {
            // 解析 URL 中的参数（?后面的部分）
            String query = url.substring(queryIndex + 1);
            Map<String, String> urlParams = parseQueryString(query);
            parameter.setUrlParams(urlParams);
            // URL 部分取 ? 之前的路径
            parameter.setUrl(url.substring(0, queryIndex));
        } else {
            // 无参数的 URL
            parameter.setUrl(url);
        }
    }
    //解析单行请求头，存入 headers 映射
    private static void parseHeaderLine(String headerLine, Parameter parameter) {
        int colonIndex = headerLine.indexOf(':');
        if (colonIndex == -1) {
            return; // 忽略无效头
        }
        String key = headerLine.substring(0, colonIndex).trim();
        String value = headerLine.substring(colonIndex + 1).trim();
        parameter.addHeader(key, value);
    }
   //解析请求体
   private static void parseRequestBody(BufferedReader reader, Parameter parameter) throws IOException {
       // 从请求头获取 Content-Length，确定请求体长度
       String contentLengthStr = parameter.getHeaders().get("Content-Length");
       if (contentLengthStr == null || contentLengthStr.isEmpty()) {
           return; // 无 Content-Length 则不处理
       }
       int contentLength;
       try {
           contentLength = Integer.parseInt(contentLengthStr);
       } catch (NumberFormatException e) {
           throw new IOException("无效的 Content-Length: " + contentLengthStr);
       }
       // 读取请求体内容（按长度读取，避免读取到下一个请求）
       char[] bodyChars = new char[contentLength];
       int read = reader.read(bodyChars, 0, contentLength);
       if (read != contentLength) {
           throw new IOException("请求体长度与 Content-Length 不匹配");
       }
       String body = new String(bodyChars);

       // 解析表单数据（默认处理 application/x-www-form-urlencoded 类型）
       String contentType = parameter.getHeaders().get("Content-Type");
       if (contentType != null && contentType.contains("application/x-www-form-urlencoded")) {
           Map<String, String> bodyParams = parseQueryString(body);
           parameter.setBodyParams(bodyParams);
       }
   }
   //解析查询字符串
   private static Map<String, String> parseQueryString(String query) throws IOException {
       Map<String, String> params = new HashMap<>();
       if (query == null || query.isEmpty()) {
           return params;
       }

       String[] pairs = query.split("&");
       for (String pair : pairs) {
           int eqIndex = pair.indexOf('=');
           if (eqIndex == -1) {
               // 只有键没有值（如 a&b=2）
               String key = URLDecoder.decode(pair, StandardCharsets.UTF_8.name());
               params.put(key, "");
           } else {
               // 键值对（如 a=1）
               String key = URLDecoder.decode(pair.substring(0, eqIndex), StandardCharsets.UTF_8.name());
               String value = URLDecoder.decode(pair.substring(eqIndex + 1), StandardCharsets.UTF_8.name());
               params.put(key, value);
           }
       }
       return params;
   }

}
